local Msg = require("core.Msg")
local Util = require("common.Util")
local Grid = require("bag.Grid")
local ItemDefine = require("bag.ItemDefine")
local TuJianExcel = require("excel.equip").tujian
local EquipExcel = require("excel.equip").equip
local ItemExcel = require("excel.item").item
local EquipLogicGrid = require("equip.EquipLogicGrid")
local Log = require("common.Log")
local LogDefine = require("common.LogDefine")
local Lang  = require("common.Lang")
local Broadcast = require("broadcast.Broadcast")
local MailManager = require("mail.MailManager")
local MailExcel = require("excel.mail")
local HeroLogic = require("hero.HeroLogic")

EQUIP_BAG_MAX_CNT = 300
EQUIP_BAG_OP_ADD = 1 -- 增
EQUIP_BAG_OP_DEL = 2 -- 删
EQUIP_BAG_OP_CHANGE = 3 -- 改

EQUIP_QUALITY_MAX = 5
EQUIP_QUALITY = { 5000, 3000, 1500, 500 }
EQUIP_QUALITY_WEIGHT = 10000
EQUIP_QUALITY_BASE_RATE = { 7000, 8000, 9000, 10000, 12000 }


-- 随机属性
local attrCheck = {}
function checkAttr(equipGrid)
   local quality = equipGrid.quality
   local len = 0

   for key, value in pairs(equipGrid.attr) do
      len = len + 1
      attrCheck[len] = {key, value}
   end

   -- 砍掉后面的
   if quality < len then   
      equipGrid.attr = {}   
      for z = 1, quality do
         equipGrid.attr[attrCheck[z][1]] = attrCheck[z][2]
      end
   end
end

-- 随机属性
function randomAttr(itemID, isRandom, otherData)
    local equipConfig = EquipExcel[itemID]
    if not equipConfig then return end

    -- 固定属性
    local quality = 1
    local attr = { }
    if equipConfig.random == 1 and not isRandom then
        quality = #equipConfig.randomAttr
        if quality > EQUIP_QUALITY_MAX then
           quality = EQUIP_QUALITY_MAX
        end

        for i = 1, quality do
            local key = equipConfig.randomAttr[i][1]
            local value = equipConfig.randomAttr[i][2]
            attr[key] = attr[key] or 0
            attr[key] = attr[key] + value
        end
        return attr, quality
    end

    if not otherData then
    -- 随机品质
       local random = math.random(1, EQUIP_QUALITY_WEIGHT)
       for i = 1, #EQUIP_QUALITY do
           local weight = EQUIP_QUALITY[i]
           if random <= weight then
               quality = i > #equipConfig.randomAttr and #equipConfig.randomAttr or i
               break
           else
               random = random - weight
           end
       end
    else
       if type(otherData) == "number"  then
          otherData = otherData < 0 and 1 or otherData
          quality = otherData > #equipConfig.randomAttr and #equipConfig.randomAttr or otherData 
       end
    end

    if quality > EQUIP_QUALITY_MAX then
       quality = EQUIP_QUALITY_MAX
    end


    -- 计算总权重
    local totalWeight = 0
    for k, v in pairs(equipConfig.randomAttr) do
        totalWeight = totalWeight + v[3]
    end

    -- 随机条目属性
    local MathRandom = math.random
    local randomAttr = Util.copyTable(equipConfig.randomAttr)
    
    for z = 1, quality do
        local randmWeight = MathRandom(1, totalWeight)
        for k, v in pairs(randomAttr) do
            local key = v[1]
            local value = v[2]
            local weight = v[3]
            if randmWeight <= weight then
                attr[key] = attr[key] or 0
                attr[key] = attr[key] + value
                randomAttr[k] = nil
                -- 排除这个权重
                totalWeight = totalWeight - weight
                break
            else
                randmWeight = randmWeight - weight
            end
        end
    end

    return attr, quality
end

-- 检查背包空间
function checkEmptyCnt(human, itemCnt)
   if itemCnt > getEmptyCnt(human) then
      Broadcast.sendErr(human, Lang.COMMON_BAG_FULL)
      return 
   end
   return true
end


-- 获取装备对基础属性的影响
function getEquipBaseRate(quality)
    local baseRate = EQUIP_QUALITY_BASE_RATE[quality]
    if not baseRate then return 1 end
    return baseRate / 10000
end

-- 获取装备品质
function getEquipMaxQuality(equipConfig)
    if not equipConfig.randomAttr then return 0 end

    local maxQuality = 0
    if equipConfig.random == 1 then
        maxQuality = #equipConfig.randomAttr
    end
    return maxQuality
end

-- 获取装备附加属性
function getEquipTzAttr(equipConfig)
    if not equipConfig.randomAttr then return end
    if equipConfig.random == 1 then
       return equipConfig.randomAttr
    end
    return nil
end

-- 返回装备背包空余格子数
function getEmptyCnt(human)
    local emptyCnt = 0
    for i = 1, EQUIP_BAG_MAX_CNT do
        if human.db.equipBag[i] == nil then
            emptyCnt = emptyCnt + 1
        end
    end
    return emptyCnt
end


-- 获得装备背包第一个空格子下标
function getEmptyIndex(human)
    for index = 1, EQUIP_BAG_MAX_CNT do
        local grid = human.db.equipBag[index]
        if grid == nil then
            return index
        end
    end
end

-- 返回装备根据uuid
function getEquipByUuid(human, uuid)
    local emptyCnt = 0
    for i = 1, EQUIP_BAG_MAX_CNT do
        local equipGrid = human.db.equipBag[i]
        if equipGrid and equipGrid.uuid == uuid then
            return equipGrid
        end
    end
end

-- 返回装备根据pos
function getEquipByPos(human, star, pos)
    local emptyCnt = 0
    for i = 1, EQUIP_BAG_MAX_CNT do
        local equipGrid = human.db.equipBag[i]
       
        if equipGrid then
            local conf = EquipExcel[equipGrid.id]
            if conf and conf.subType == pos and star >= conf.star then
               return equipGrid
            end
        end
    end
end

-- 修复老数据
function modifyEquip(human, equipGrid)
   if equipGrid.putUuid == nil then return end
   local heroGrid = HeroLogic.getHeroGridByUuid(human, equipGrid.putUuid)
   if heroGrid == nil then
      equipGrid.putUuid = nil
   end
end

-- 推送装备背包信息
function sendEquipBagList(human)
    local msgRet = Msg.gc.GC_EQUIP_BAG_LIST
    local len = 0
    for index = 1, EQUIP_BAG_MAX_CNT do
        local equipGrid = human.db.equipBag[index]
        if equipGrid then
            len = len + 1
            Grid.makeItem(msgRet.list[len], equipGrid.id, 1, nil, equipGrid, index, Grid.getOpflagAtBag(equipGrid.id))
            if len >= 30 then
                msgRet.list[0] = len
                len = 0
                Msg.send(msgRet, human.fd)
            end
        end
    end
    if len > 0 then
        msgRet.list[0] = len
        Msg.send(msgRet, human.fd)
    end
end

-- 制造一个获得列表
function makeEquipItem(human, nets, len)
    if not human.getEquip then return len end

    for i = 1, #human.getEquip do
        len = len + 1
        if not nets[len] then
            len = len - 1
            break
        end

        local equipGrid = human.getEquip[i]
        Grid.makeItem(nets[len], equipGrid.id, 1, nil, equipGrid)
    end
    human.getEquip = nil

    return len
end

-- 制造一个装备获得
function makeEquipItemOne(human, net)
    if not human.getEquip then return end
    local equipGrid = human.getEquip[1]
    Grid.makeItem(net, equipGrid.id, 1, nil, equipGrid)
    human.getEquip = nil
end

-- 制造一个装备
function makeEquip(itemID, otherData)
   local equipGrid = EquipLogicGrid.createGrid(itemID)
   if not equipGrid then return end

   -- 随机属性
   local attr, quality = randomAttr(itemID, nil, otherData)
   equipGrid.attr = attr
   equipGrid.quality = quality
   checkAttr(equipGrid)
   return equipGrid
end

-- 添加装备
function addEquip(human, itemID, itemCnt, logType, otherData)
    if not EquipExcel[itemID] then return end
   
    for i = 1, itemCnt do
        local equipGrid = makeEquip(itemID, otherData)
        if equipGrid then
           addByEquipGrid(human, equipGrid, logType)
        end
    end
end

-- 通过gird添加装备
function addByEquipGrid(human, equipGrid, logType, noSend)
    local index = getEmptyIndex(human)
    if not index then 
       --邮件处理
       local items = {}
	   items[1] = { equipGrid.id, equipGrid }
   	   local title = MailExcel.mail[1000].title
	   local content = MailExcel.mail[1000].content
	   local senderName = MailExcel.mail[1000].senderName
	   MailManager.add(MailManager.SYSTEM, human.db._id, title, content, items, senderName)
       return 
    end

    human.db.equipBag[index] = equipGrid
    sendEquipChange(human, index, equipGrid, EQUIP_BAG_OP_ADD)

    Log.write(Log.LOGID_OSS_EQUIP, human.db._id, human.db.account,
    human.db.name, human.db.lv, LogDefine.DEFINE[logType] + LogDefine.TYPE["equip"], equipGrid.id, 1, equipGrid.uuid)

    if not noSend then
       human.getEquip = human.getEquip or {}
       human.getEquip[#human.getEquip + 1] = equipGrid
    end
    return index
end

-- 从背包删除装备
function delEquip(human, index, logType, sendNotify)
    local equipGrid = human.db.equipBag[index]
    if not equipGrid then return end

    Log.write(Log.LOGID_OSS_EQUIP, human.db._id, human.db.account,
    human.db.name, human.db.lv, LogDefine.DEFINE[logType] + LogDefine.TYPE["equip"], equipGrid.id, -1, equipGrid.uuid)

    human.db.equipBag[index] = nil

    if not sendNotify then
       sendEquipChange(human, index, nil, EQUIP_BAG_OP_DEL)
    end
end

-- 发送装备改变
function sendEquipChange(human, bagIndex, equipGrid, op)
    local msgRet = Msg.gc.GC_EQUIP_BAG_CHANGE
    if op == EQUIP_BAG_OP_ADD or op == EQUIP_BAG_OP_CHANGE then
        msgRet.itemID = equipGrid.id
        msgRet.itemIndex = bagIndex
        msgRet.itemData[0] = 1
        Grid.makeItem(msgRet.itemData[1], equipGrid.id, 1, nil, equipGrid, bagIndex, Grid.getOpflagAtBag(equipGrid.id))
    elseif op == EQUIP_BAG_OP_DEL then
        msgRet.itemID = 0
        msgRet.itemIndex = bagIndex
        msgRet.itemData[0] = 0
    else
        assert(nil)
    end
    Msg.send(msgRet, human.fd)
end


function getNewAttrByItemID(itemID, attr) 
    local config = EquipExcel[itemID]
    if not config then return end

    for _, v in ipairs(config.randomAttr) do
        if attr[v[1]] then
            attr[v[1]] = v[2]
        end
    end
end